package com.sergio.compress.cp.mainUtil;

import com.github.luben.zstd.ZstdInputStream;
import com.github.luben.zstd.ZstdOutputStream;
import com.sergio.compress.cp.base.CompressResult;
import com.sergio.compress.cp.base.CompressTest;
import com.sergio.compress.cp.base.DecompressResult;
import com.sergio.compress.cp.base.TestSource;
import org.springframework.util.StopWatch;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Date;

/**
 * @Author : Sergio.D
 * @Description :
 * @CreateDate ：2023/6/14 16:21
 */
public class ZSTD_DEL extends CompressTest {


    public CompressResult compress(byte[] data) {
        //判断byte[]为空
        if (data == null || data.length == 0) {
            return null;
        }
        StopWatch stopWatch = new StopWatch();
            stopWatch.start();

        ByteArrayOutputStream compressedStream = new ByteArrayOutputStream();
        try (ZstdOutputStream zstdOutputStream = new ZstdOutputStream(compressedStream)) {
            zstdOutputStream.write(data);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        byte[] compressed = compressedStream.toByteArray();
        stopWatch.stop();
        return new CompressResult(getType(), stopWatch.getTotalTimeNanos(), compressed, data.length, compressed.length);
    }

    public DecompressResult decompress(byte[] compressedData, int lengthSource) {
        if (compressedData == null || compressedData.length == 0) {
            return null;
        }
        StopWatch stopWatch = new StopWatch();
            stopWatch.start();

        ByteArrayInputStream compressedInputStream = new ByteArrayInputStream(compressedData);
        ByteArrayOutputStream decompressedStream = new ByteArrayOutputStream();
        try (ZstdInputStream zstdInputStream = new ZstdInputStream(compressedInputStream)) {
            byte[] buffer = new byte[lengthSource];
            int bytesRead;
            while ((bytesRead = zstdInputStream.read(buffer)) > 0) {
                decompressedStream.write(buffer, 0, bytesRead);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        byte[] decompressedData = decompressedStream.toByteArray();

        stopWatch.stop();
        return new DecompressResult(getType(), stopWatch.getTotalTimeNanos(), decompressedData, lengthSource, decompressedData.length);
    }

    @Override
    public String getType() {
        return "ZSTD";
    }

    @Override
    public CompressResult compress(TestSource testSource) {
        return compress(testSource.getSourceData());
    }

    @Override
    public DecompressResult decompress(CompressResult testSource) {
        return decompress(testSource.getData(), testSource.getLengthSource());
    }
}
